package com.example.demo.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

/**
 * @author wangsl
 * @date 2020/7/5 20:09
 * <p>
 * Description:
 */
//排除容器中Dog bean的注入
//@ComponentScan(basePackages = "com.example.demo.spring", excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = DogConfig.class))
//@Configuration
public class App {

    public static void main(String[] args) {
        //1.传入一个或者多个配置Bean
        /*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                AppConfig.class,
                User.class,
                UserDao.class,
                UserService.class,
                UserController.class
        );*/
        //2.通过扫描包的方式加载上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.example.demo.spring");
        // 3.同样使用扫描包的方式,不过使用的是注解@ComponentScan("com.example.demo.spring")和@Configuration
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
        System.out.println(context.getBean("myBean"));
        System.out.println(context.getBean(MyBean.class));
        System.out.println(context.getBean(RunnableFactoryBean.class));
        //获取RunnableFactoryBean本身
        System.out.println(context.getBean("&createRunnableFactoryBean"));
        //com.example.demo.spring.Jeep@7ce3cb8e
        System.out.println(context.getBean(Jeep.class));
        //com.example.demo.spring.Jeep@78b66d36,RunnableFactoryBean特殊的bean用来创建Jeep对象的Bean
        System.out.println(context.getBean("createRunnableFactoryBean"));
        //先创建工厂bean,再通过工厂bean创建bean对象
        System.out.println(context.getBean("createCar"));
        //bean的属性设置之前和设置之后的操作
        System.out.println(context.getBean(Cat.class));
        //通过@Bean(initMethod = "init", destroyMethod = "destroy")设置
        System.out.println(context.getBean(Dog.class));
        //通过@PostConstruct和@PreDestroy注解设置
        System.out.println(context.getBean(Bird.class));
        //@Component(没有明确角色的时候使用)注解表示其是容器的一个组件,无法设置初始和销毁方法操作
//        System.out.println(context.getBean(User.class));
        System.out.println(context.getBeansOfType(User.class));
        System.out.println(context.getBean("myUser"));
        System.out.println(context.getBean("createUser"));
        //@Repository也可以将对象注入为容器中的bean,用于持久访问层
//        System.out.println(context.getBean(UserDao.class));
        //@Service一般用于业务逻辑层,注入bean
        System.out.println(context.getBean(UserService.class));
        ////@Controller用于展示控制层
        System.out.println(context.getBean(UserController.class));
        User user = context.getBean("myUser", User.class);
        System.out.println(user);

        context.close();
    }
}
